import React, { useEffect, useState } from 'react';
import { Button, message, Modal, Upload as AUpload } from 'antd';
import { ArrowLeftOutlined, ArrowRightOutlined, PlusOutlined, UploadOutlined } from '@ant-design/icons';
import { http } from 'libs';
import lds from 'lodash';
import css from './index.module.less';

export default function Upload(props) {
  const [previewVisible, setPreviewVisible] = useState(false)
  const [previewImage, setPreviewImage] = useState('')
  const [fileList, setFileList] = useState([])

  useEffect(() => {
    let value = props.value
    if (!props.value) {
      value = []
    } else if (typeof value === 'string') {
      value = [value]
    }
    if (!lds.isEqual(value, fileList.filter(x => x.status === 'done').map(x => x.url))) {
      setFileList(value.map((x, index) => {
        return ({
          uid: `-${index + 1}`,
          url: x,
          name: x.slice(x.lastIndexOf('/') + 1),
          status: 'done'
        })
      }))
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [props.value])

  function getExtraData(file) {
    const suffix = file.name.slice(file.name.lastIndexOf('.'))
    return http.get('/api/oss/sign/', { params: { suffix } })
      .then(res => {
        file.url = `${res.host}/${res.key}`
        file.extraData = res
        return res.host
      })
  }

  function handlePreview(file) {
    setPreviewImage(file.url || file.thumbUrl)
    setPreviewVisible(true)
  }

  function handleChange({ fileList }) {
    setFileList(fileList)
    const files = fileList.filter(x => x.status === 'done')
    let value = files.map(x => x.url)
    if (!lds.isEqual(props.value || [], value)) {
      if (props.maxCount === 1) value = value.length ? value[0] : undefined
      props.onChange(value, files?.[0]?.name ?? '')
    }
  }

  function handleSort(file, action) {
    let index2 = null
    const index = lds.findIndex(fileList, file)
    if (action === 'left' && index !== 0) index2 = index - 1
    if (action === 'right' && index < fileList.length - 1) index2 = index + 1
    if (index2 !== null) {
      [fileList[index], fileList[index2]] = [fileList[index2], fileList[index]]
      handleChange({ fileList: [...fileList] })
    }
  }

  function beforeUpload(file) {
    if (props.listType !== 'text' && file.size > 10 * 1024 * 1024) {
      message.error('请上传小于10M的图片')
      file.status = 'error'
      return false
    }
  }

  const uploadButton = props.listType === 'text' ? (
    <Button icon={<UploadOutlined />}>点击上传</Button>
  ) : (
    <div>
      <PlusOutlined />
      <div className="ant-upload-text">点击上传</div>
    </div>
  )

  return (
    <div>
      <AUpload
        accept={props.listType === 'text' ? '*' : 'image/*'}
        action={getExtraData}
        disabled={props.disabled}
        listType={props.listType}
        maxCount={props.maxCount}
        showUploadList={{ showPreviewIcon: true }}
        data={file => file.extraData}
        fileList={fileList}
        beforeUpload={beforeUpload}
        isImageUrl={() => props.listType !== 'text'}
        onPreview={props.listType === 'text' ? undefined : handlePreview}
        itemRender={(originNode, file, currFileList) => props.sortable ? (
          <div className={css.uploadSort}>
            {originNode}
            <ArrowLeftOutlined className={css.left} onClick={() => handleSort(file, 'left')} />
            <ArrowRightOutlined className={css.right} onClick={() => handleSort(file, 'right')} />
          </div>
        ) : originNode}
        onChange={handleChange}>
        {(props.maxCount && fileList.length >= props.maxCount) ? null : uploadButton}
      </AUpload>
      <Modal open={previewVisible} footer={null} onCancel={() => setPreviewVisible(false)}>
        <img alt="example" style={{ width: '100%', marginTop: 24 }} src={previewImage} />
      </Modal>
    </div>
  )
}

Upload.defaultProps = {
  private: false,
  sortable: false,
  maxCount: 1,
  listType: 'picture-card',
  onChange: () => null
}
